home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
lang
/
d86bios4
/
zbios1.8
< prev
next >
Wrap
Text File
|
1989-07-07
|
35KB
|
960 lines
;------------------
; WANG INTERFACE
;------------------
; Thanks to Alan Tschetter for providing the information necessary for me
; to program this interface.
WANG_KEYS:
DB 0E1 ; HELP key value
DB 07F-FUNC ; add-quantity for FUNC
L1:
DB 0C2,0C9,0C0,0C8,0C4 ; DOWN, NEXT, UP, PREV, HOME
DB 097,097 ; shift-F7 key, disabled Alt-F9 key
N_CONTROL_KEYS EQU $-L1
DW HELP_HELP ; pointer to "HELP" message, the name of Wang's HELP key
L2:
DW WANG_COPY ; VID_COPY routine
DW WANG_ATTR ; VID_ATTR routine
DW RET ; there is no VID_FIX necessary on the Wang
DW WANG_BELL ; BIOS_BELL routine
DW WANG_KEY ; BIOS_KEY routine
DW RET
DW RET
DW 0F000 ; new value for VIDEO_SEG
DB 0 ; normal-video attribute for the Wang PC
DB 2 ; reverse-video attribute for the Wang PC
N_BIOS_CALLS EQU ($-L2)/2
; Other Wang keycodes: F1--F16 80--8F
; Prev C8 Erase CB
; Insert C6 Delete C7
; <--- C3 ---> C1
; EXEC C5
; All the above codes add 010 for SHIFT versions.
; NO ALT KEY!!!
; Print E3 Back Tab CD
; Cancel E0 Shift Cancel 03
; WANG_CONFIG is the BIOS initialization routine for a Wang PC. We copy the
; values of WANG_KEYS to various locations, then we fetch the value of
; ENABLE_PORT, that lets us access Wang's video memory, then we move the
; user's cursor to the lower left corner.
L1: ; console codes to move cursor to lower left corner
DB 01B,'[25;1H' ; row 25, column 1
L2 EQU $-L1 ; L2 is the count of bytes
WANG_CONFIG:
MOV SI,WANG_KEYS ; point to Wang's table of key codes and other values
CALL NEW_KEYS ; plug the new values into our program's data structures
MOV AL,1 ; function code for GET BIOS ENVIRONMENT
INT 088 ; sets ES to a segment where we'll find port #
ES MOV BX,[BX+10] ; fetch a pointer
ES MOV AH,[BX+19] ; use the pointer to fetch the high of the port #
MOV AL,010 ; low of the port # is always 010
MOV ENABLE_PORT,AX ; store the port number
MOV DS,CS ; point DS to our program, for console sequence
MOV DX,L1 ; point DX to the "go to lower left" console sequence
MOV CX,L2 ; load the number of bytes in the sequence
MOV BH,0 ; device number, maybe? I don't know for sure
MOV AL,0D ; function number, maybe? I don't know for sure
INT 088 ; output escape string, user's cursor goes to lower left
RET
; WANG_COPY is the Wang-PC version of the VID_COPY routine. The character
; and attribute bytes are reversed from what they are on the IBM-PC, so
; AH and AL are swapped before and after every word output. There are no
; snow problems; so we can get away with copying everything every time.
; We do need to enable the video memory, though.
WANG_COPY:
MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
MOV AL,1 ; value 1 causes memory to be enabled
OUT DX,AL ; we can now access the video memory
L1: ; loop here for each character to be copied
LODSB ; fetch the next character
XCHG AH,AL ; swap character into AH, attribute byte into AL
STOSW ; output the word to video memory
MOV AH,AL ; copy the attribute byte back to AH, for next char
LOOP L1 ; loop to copy the next character
L2: ; common exit with WANG_ATTR
MOV AL,0 ; value 0 shuts off access to video memory
OUT DX,AL ; video access is now disabled
RET
; WANG_ATTR is the Wang-PC version of the VID_ATTR routine. The attribute
; byte is the low byte of the DI-pointed video memory. Also, to access it,
; we must send the code that enables Wang video memory.
WANG_ATTR:
PUSH AX ; preserve the attribute code
MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
MOV AL,1 ; value 1 causes memory to be enabled
OUT DX,AL ; we can now access the video memory
POP AX ; restore the attribute code
STOSB ; output the attribute byte to the LOW byte of video word
JMP L2 ; join common code to disable video access
; WANG_KEY is the Wang-PC version of the BIOS_KEY routine.
WANG_KEY:
PUSH BX ; preserve register across call
L1: ; loop here to wait for a key to become ready
MOV AL,15 ; Wang BIOS function code for GET KEY STATUS
MOV BL,2 ; another parameter for Wang BIOS - I'm not sure which
INT 088 ; call Wang BIOS to get the status and maybe the key
TEST AL ; do we have a key?
JNZ L1 ; loop if not, to try again
XCHG AX,BX ; we do: swap the key code into AL for return
POP BX ; restore clobbered register
RET
; WANG_BELL is the Wang-PC version of the BIOS_BELL routine.
WANG_BELL:
MOV BX,7 ; BL=7 is the BELL code; the BIOS also wants BH=0
MOV AL,6 ; Wang BIOS function code for CONSOLE OUTPUT
INT 088 ; output the BELL control code to the Wang console
RET
;------------------
; TI-PC INTERFACE
;------------------
; Thanks to David R. Cook for writing the following code. I have reformatted
; it to look like the rest of my code, and made optimizations.
TIPC_KEYS:
DB 0B5 ; key code for F11 - the help key
DB 0AA-FUNC ; F1 is code 0AB on the TI-PC
L1:
DB 0C0 ; down-arrow key
DB 0C1 ; no PgDn key on the TI-PC, so we use alt-down-arrow code
DB 0B8 ; up-arrow key
DB 0B9 ; no PgUp key on the TI-PC, so we use alt-up-arrow code
DB 0B7 ; HOME key
DB 0CA ; shift-F7 key
DB 0E0 ; alt-F9 key
N_CONTROL_KEYS equ $-L1
DW F11_HELP ; pointer to help message
L2:
DW TIPC_COPY ; VID_COPY routine
DW TIPC_ATTR ; VID_ATTR routine
DW TIPC_FIX ; VID_FIX routine
DW TIPC_BELL ; BIOS_BELL routine
DW TIPC_KEY ; BIOS_KEY routine
DW RET
DW RET
DW 0DE00 ; new value for VIDEO_SEG
DB 0F ; normal-video attribute for the TI-PC
DB 01F ; reverse-video attribute for the TI-PC
N_BIOS_CALLS equ ($-L2)/2
; Other TI keycodes:
; key +shift +alt +ctrl plain
; ----------------------------------
; F1 0C4 0D8 0CE 0AB
; ...
; F10 0CD 0E1 0D7 0B4
; F11 "x" "|" "z" 0B5
; F12 "y" "}" "{" 0B6
;
; PRNT 0E2
; INS 098 09A 099 0C2
; DEL 0A8 0AA 0A9 0C3
; UP AR 0F8 0B9 0F4
; DN AR 0F9 0C1 0E6
; LT AR 0FB 0BC 0E3 0BB
; RT AR 0FA 0BE 0E4 0BD
; HOME 0F6 0F5 0E7
; TAB 07F ignored ignored 09
; TIPC_CONFIG is the BIOS initialization routine for the TI-PC. We copy the
; values in TIPC_KEYS to various locations, then we drop into TIPC_FIX,
; to reset the cursor.
TIPC_CONFIG:
MOV SI,TIPC_KEYS ; point to configuration-table for TI-PC's BIOS
CALL NEW_KEYS ; copy the values to our tables
TIPC_FIX:
MOV AH,014 ; BIOS function code for "clear graphics screen"
INT 049 ; clear the graphics screen
MOV AH,013 ; BIOS function code for "clear text screen"
INT 049 ; clear the text screen
MOV AH,2 ; BIOS function code for "position the cursor"
MOV DX,1 BY 24 ; first column, 24th row
INT 049 ; move the user's cursor to the bottom left corner
RET
; TIPC_COPY is the VID_COPY routine for the TIPC video board. The attribute
; AH is written to a single memory-mapped latch in the video segment.
; Then the text bytes can be copied as-is.
TIPC_COPY:
ES MOV B[01801],AH ; set the attribute latch
SHR DI,1 ; adjust the video address for bytes, not words
REP MOVSB ; copy the text as-is
SHL DI,1 ; restore the video address to words, not bytes
RET
; TIPC_ATTR is the VID_ATTR routine for TI-PC computer. We change the
; attribute latch to the one provided in AL, then we add 0 to the video
; character in memory, causing the new latch value to take effect.
TIPC_ATTR:
SHR DI,1 ; adjust video address for bytes, not words
ES MOV AH,B[DI] ; fetch the character
ES MOV B[01801],AL ; rewrite the latch with the caller's value
ES MOV B[DI],AH ; re-write the value already there, to effect the latch
SHL DI,1 ; restore DI
RET
; TIPC_KEY is the BIOS_KEY routine for TI_PC computer. We must transform the
; two-byte code returned by the TIPC BIOS into the single code AL expected by
; the rest of the debugger. The only differences to IBM_KEY are the interrupt
; number, and the mapping of the codes received and returned.
TIPC_KEY:
MOV AH,0 ; function code for GET KEY
INT 04A ; get the keystroke from the TIPC BIOS
TEST AL ; is the return AL nonzero?
JNZ RET ; if yes then AL is our return code
MOV AL,AH ; AL is zero, so AH determines the return code
ADD AL,080-16 ; shift the values into a range not seen directly in AL
RET
; TIPC_BELL is the BIOS_BELL routine for TIPC-PC computer. We output the code
; 07 to the BIOS's console output routine. The only difference to IBM_KEY is
; the interrupt number.
TIPC_BELL:
MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
INT 049 ; output BELL to the console
RET
;------------------
; SANYO INTERFACE
;------------------
; Thanks to Jerry Farnsworth for providing the information necessary for me
; to program this interface.
SANYO_KEYS:
DB 0DC ; key code for Ctrl-PF5 -- the help key
DB 0 ; same function codes as IBM-PC
L1:
DB 0C0 ; down-arrow key
DB 0C1 ; PgDn key
DB 0B8 ; up-arrow key
DB 0B9 ; PgUp key
DB 0B7 ; HOME key
DB 0CA ; shift-F7 key is Ctrl 7 on the Sanyo
DB ALT_F 9 ; Ctrl-Shift-PF4 will restore a trashed screen
N_CONTROL_KEYS equ $-L1
DW PF5_HELP ; pointer to help message
L2:
DW SANYO_COPY ; VID_COPY routine
DW SANYO_ATTR ; VID_ATTR routine
DW NO_ACTUAL ; VID_FIX routine
DW IBM_BELL ; BIOS_BELL routine
DW IBM_KEY ; BIOS_KEY routine
DW SANYO_SAVE ; we must save the BIOS cursor position
DW SANYO_RESTORE ; we must restore the BIOS cursor position
DW 07C00 ; new value for VIDEO_SEG
DB 07 ; normal-video attribute for the Sanyo-PC
DB 0F0 ; reverse-video attribute for the Sanyo-PC
N_BIOS_CALLS equ ($-L2)/2
; Other Sanyo keycodes:
; IBM Sanyo IBM Sanyo
; Alt Ctrl Shift DOWN numeric pad 5
; Alt Fn Ctrl Fn END numeric pad 2
; Shift Fn Ctrl n
; Ctrl 2 Ctrl ` Ctrl F12345 Ctrl ={}:"
; Ctrl 6 Ctrl tilde Ctrl F678910 Ctrl ;',./
; SANYO_CONFIG is the BIOS initialization routine for a Sanyo 55x. We copy the
; values of SANYO_KEYS to various locations, fetch and store the current
; video page, and set the user cursor to the lower left of the screen.
; SANYO_FIX insures a screen refresh by filling the "actual" buffers of SCREEN_P
; with impossible FF-values.
SANYO_CONFIG:
MOV SI,SANYO_KEYS ; point to configuration-table for SANYO's BIOS
CALL NEW_KEYS ; copy the values to our tables
MOV AH,15 ; function number for fetching the video page
INT 010 ; set BH to the current video page
MOV SANYO_PAGE,BH ; store the page throughout the debugging session
MOV DX,24 BY 0 ; load coordinates for the lower left corner
CALL SET_SANYO_POS ; store this position
CALL SANYO_RESTORE ; this call causes the user cursor to move there
NO_ACTUAL:
MOV AX,0FFFF ; load AH and AL with the 0FF impossible-value
FILL_ACTUAL:
MOV ES,SS ; destination segment is our stack, for buffer-fill
XCHG DI,AX ; save fill-value in DI
SS MOV AX,SCREEN_P ; point to the screen buffer
MOV AL,80 ; advance AX to the actual buffer for the first line
XCHG AX,DI ; swap actual pointer to DI, restore fill value to AX
MOV DL,24 ; load the count of actual lines to fill
L2:
MOV CX,40 ; number of words in the actual buffer
REP STOSW ; fill the buffer with the words
ADD DI,256-80 ; advance output pointer to the next line's actual buff.
DEC DL ; count down lines
JNZ L2 ; loop to fill the next line
RET
; SANYO_COPY is the VID_COPY routine for the Sanyo. The Sanyo does not have
; a hardware character generator, so we call the BIOS to copy bit-patterns
; to the screen.
SANYO_COPY:
PUSH BX,BP ; preserve caller's BX and return DI value
MOV BP,>L3
MOV BH,0 ; load the page number
SANYO_PAGE EQU B[$-1] ; previous immediate value is plugged in
BP_VID_COPY:
MOV AX,DI ; fetch the output character number
ADD DI,CX ; add the character count
ADD DI,CX ; add it twice, to advance by words not bytes
PUSH DI
CALL GET_ROWCOL ; convert character number AX into row-and-column DX
DEC DX ; cancel the following first INC DX
L1: ; loop here for every character already out there
INC DX ; advance the column number DL to the next position
LODSB ; fetch the next character
MOV BL,AL ; save the character in BL
XCHG AL,[SI+79] ; swap it with the already-out-there value
CMP AL,BL ; is the character already out there?
LOOPE L1 ; loop if it is
JE >L2 ; jump if the characters are exhausted
INC CX ; undo the previous LOOPE's decrement of CX
CALL BP
LOOP L1 ; loop to check for another output character
L2:
POP DI,BP,BX ; restore clobbered registers
RET
L3:
CALL SET_IBM_CURSOR ; move the cursor to the indicated position
MOV AL,BL ; fetch the character to be output
MOV BL,7 ; load the attribute code, always 7 in Sanyo's case
PUSH CX ; save the character count
MOV CX,1 ; we are outputting 1 character in this call
MOV AH,9 ; BIOS function number for WRITE_CHAR
INT 010 ; write the character to the screen
POP CX ; restore the character count
RET
; SANYO_ATTR is the VID_ATTR routine for the Sanyo. We use the BIOS to
; move the cursor to the current position, read the character that is
; already there, and rewrite the character with the new attribute.
SANYO_ATTR:
PUSH BX,CX,DX,DI ; save registers across call
PUSH AX ; save the attribute across the repositioning
MOV AX,DI ; fetch the character number
CALL GET_ROWCOL ; convert the character number AX to row-and-column DX
CS MOV BH,SANYO_PAGE ; load the current page number
CALL SET_IBM_CURSOR ; move the cursor to the required location
MOV AH,8 ; function number for READ_CHARACTER
INT 010 ; set AL to the character already there
POP DX ; restore DL = new attribute byte
MOV BL,DL ; copy the attribute to BL where the BIOS expects it
MOV CX,1 ; we are writing one character only
MOV AH,9 ; BIOS function number for WRITE_CHAR
INT 010 ; write the character to the screen
POP DI,DX,CX,BX ; restore clobbered registers
RET
; GET_ROWCOL an address AX into a row number DH and column number DL. The input
; AX address is twice the number of characters from the start of the screen
; to the current cursor position.
GET_ROWCOL:
SHR AX,1 ; convert the word index into a byte index
MOV DL,80 ; there are 80 characters in a line
DIV DL ; compute the column number AH, row number AL
XCHG AL,AH ; swap so AH is row, AL is column
XCHG DX,AX ; swap so DH is row, DL is column
RET
; SANYO_SAVE is the BIOS_SAVE routine for the Sanyo. We record the user's
; cursor position, so that it can be restored by BIOS_RESTORE.
SANYO_SAVE:
MOV AH,3 ; BIOS function number for READ_CURSOR_POSITION
INT 010 ; set DX to the current user cursor position
SET_SANYO_POS:
CS MOV SANYO_POS,DX ; store the cursor position DX
RET
; SANYO_RESTORE is the BIOS_RESTORE routine for the Sanyo. We set the
; user's sursor position to the place previously stored.
SANYO_RESTORE:
MOV DX,0 ; fetch the cursor position
SANYO_POS EQU W[$-2] ; the above immedaite operand has been plugged
JMP SET_IBM_CURSOR ; jump to set the user's cursor
;------------------------
; TANDY 2000 INTERFACE
;------------------------
; Thanks to John B. Harrell, Contributing Editor PC Resuorce, for writing
; the following code. I have made minor code optimizations.
TANDY_KEYS:
DB ALT_F 10 ; code for Alt-F10 -- the HELP key
DB 0 ; F1 code same as on IBM-PC
L1:
DB 0C0 ; Down Arrow
DB 0C1 ; PgDn
DB 0B8 ; Up Arrow
DB 0B9 ; PgUp
DB 0B7 ; Home
DB 0CA ; Shift F7
DB ALT_F 9 ; Alt-F9 fixes a trashed screen
N_CONTROL_KEYS EQU $-L1
DW ALTF10_HELP ; pointer to help message
L2:
DW MONO_COPY ; VID_COPY routine
DW IBM_ATTR ; VID_ATTR routine
DW TANDY_FIX ; VID_FIX routine
DW IBM_BELL ; BIOS_BELL routine
DW IBM_KEY ; BIOS_KEY routine
DW RET ; BIOS_SAVE routine needed for Sanyo only
DW RET ; BIOS_RESTORE routine needed for Sanyo only
TANDY_VSEG DW ? ; Tandy 2000 floating video segment address = VIDEO_SEG
DB 0A ; normal video attribute on Tandy 2000
DB 0CA ; reverse video attribute on Tandy 2000
N_BIOS_CALLS EQU ($-L2)/2
; Other Tandy 2000 keycodes:
; key +shift +alt +ctrl plain
; ----------------------------------
; F1 0C4 0D8 0CE 0AB
; ...
; F10 0CD 0E1 0D7 0B4
; F11 012 "&" 01C 008
; F12 013 "`" 01D 009
;
; PRNT --- 0B6 0E2 010
; INS 0F9 010 00F 0C2
; DEL 0FA 00E 00D 0C3
; UP AR 0F5 001 000
; DN AR 0F6 007 006
; LT AR 0F7 002 0E3 0BB
; RT AR 0F8 --- 0E4 0BD
; HOME 0BA 016 0E7
; TAB 07F 0FE 0FD 009
; BKSP 008 0FC 07F 008
; TAB 07F 0FE 0FD 009
; ESC 01B 0FB 01B 01B
; END --- --- 0E5 0BF
; PGUP --- --- 0F4 0B9
; PGDN --- --- 0E6
TANDY_CONFIG:
INT 012 ; get reported memory size in KBytes
MOV CL,6 ; shift count = * 64 for Kbytes to paragraphs
SHL AX,CL ; convert to paragraphs
ADD AX,0080 ; point to starting location of monochrome video buffer
CS MOV TANDY_VSEG,AX ; save in data structure
MOV SI,TANDY_KEYS ; point to configuration table for Tandy 2000
CALL NEW_KEYS ; copy the value into BIOS tables
TANDY_FIX:
MOV AX,0 BY 2 ; AH= BIOS function code for SET_VIDEO_MODE; AL = mode 0
INT 16 ; force a monochrome video mode
JMP SET_IBM_LOW_LEFT ; move the cursor to the lower left corner
;-----------------------
; SIRIUS INTERFACE
;-----------------------
; BIOS interface routines for the ACT Sirius/DRG Victor 9000. Thanks to
; Frank Peelo, Dublin, Rep. of Ireland, for writing this code. I
; have made format changes and minor optimizations.
SIRIUS_KEYS:
DB 0A ; ALT-J for help, to duplicate Wordstar
DB 0F0-FUNC ; The function keys return F0 to F8 - I don't have 9 or 10!
L1:
DB 0A1 ; Down Arrow
DB 03 ; PgDn -- must use Ctrl-C as there's no PgDn
DB 0A0 ; Up Arrow
DB 012 ; PgUp -- must use Ctrl-R as there's no PgUp
DB 0B ; Home -- Ctrl-K
DB 01A ; Shift F7
DB 0 ; no fixup needed on Sirius
N_CONTROL_KEYS EQU $-L1
DW ALTJ_HELP
L2:
DW SIRIUS_COPY ; Offsets of subroutines.
DW SIRIUS_ATTR ; For the do-nothing routines, I'll let you put in
DW RET ; no SIRIUS_FIX needed
DW SIRIUS_BELL
DW SIRIUS_KEY
DW RET ; no SIRIUS_SAVE needed
DW RET ; no SIRIUS_RESTORE needed
DW 0F000 ; segment address of the Video RAM.
DB 040 ; attribute for normal-intensity, positive video.
DB 060 ; attribute for normal-intensity, underlined video
; (reverse video is 0C0)
N_BIOS_CALLS EQU ($-L2)/2
T1: DB 01B,'Y',' '+23,' ' ; ≈ Text of VT52 escape code to move
T2 EQU $-T1 ; ≈ cursor to row 23, col 0.
; SIRIUS_BLOCK is a control block passed to INT 0DF, to get the pointer
; to the console handler routine.
SIRIUS_BLOCK:
DW 1 ; first parameter - device number (1=CON device)
SIRIUS_BIOS DD ? ; second parameter - the vector is returned here
SIRIUS_CONFIG:
MOV SI,SIRIUS_KEYS ; Point to configuration table for the Sirius
CALL NEW_KEYS ; Copy the data into D86's tables
MOV BX,SIRIUS_BLOCK
MOV AX,14 ; BIOS function 14 = Get Device Vector
INT 0DF ; The variable Sirius_BIOS_Vector is now set
MOV BX,T1 ; There is only one screen, so move the cursor
MOV CX,T2 ; I use an escape code, through Int 29h, to skip
L1: ; redirection, if it's in use
MOV AL,[BX]
PUSH BX,CX ; preserve registers across interrupt
INT 029
POP CX,BX ; restore clobbered registers
INC BX
LOOP L1
RET
; SIRIUS_COPY is the VID_COPY routine for the Sirius. On the Sirius,
; video memory consists of 2k of 16-bit words, wherein the top 5 bits
; are the attributes, and the bottom 11 a pointer to the font cell. The
; 11 bits are multiplied by 2 to give the paragraph address, since each
; character definition takes 32 bytes (16x16 pixels); the font is
; therefore in the bottom 128k of RAM. To arrive at the standard video
; font address, 100xd is added to the ASCII code using 16-bit
; arithmetic. Note that the low 3 bits of the attribute byte are 0, so
; this can occupy the high byte throughout the addition without any
; Carry-through problems.
SIRIUS_COPY:
CALL SIRIUS_ADDR ; fix ES:DI for the Sirius
MOV BH,AH ; store the attribute - calculating font addr clobbers AH
L1:
LODSB
MOV AH,BH ; the addition of 100 can't carry into the attributes
ADD AX,100 ; calculate the font address
STOSW ; save the character to the screen
LOOP L1
SUB DI,DX ; convert DI back from memory to virtual screen offset
RET
SIRIUS_ATTR: ; VID_ATTR for the Sirius
CALL SIRIUS_ADDR ; fix ES:DI for the Sirius
ES MOV BX,W[DI] ; get the character
AND BX,07FF ; mask off the attribute bits
OR BH,AL ; and put in the new value
ES MOV W[DI],BX ; put the character back
SUB DI,DX ; restore DI
RET
SIRIUS_BELL: ; BIOS_BELL for the Sirius
PUSH ES,SI,DI
MOV CL,7 ; BIOS outputs the character in CL
MOV AX,1 ; BIOS call 1 = output char
CS CALL SIRIUS_BIOS
POP DI,SI,ES
RET
; SIRIUS_KEY is the BIOS_KEY routine for the Sirius. We find the next key
; pressed, and we translate F8 into F10, and the arrow keys into single
; codes.
SIRIUS_KEY:
PUSH ES,SI,DI ; registers might be clobbered by the BIOS
SUB AX,AX ; BIOS call 0 = Console Input
CS CALL SIRIUS_BIOS
CMP AL,0F8 ; is it Fn key 8?
JNZ >L1
MOV AL,0FA ; if so, pretend it was F10
JMP >L0 ; L0 pops registers & returns
; Escape codes. The Arrow keys return <ESC>A-up, B-down, C-right & D-left
; I will use Right & Left as Page Up & Page Down, respectively.
C1:
DB 0A0,0A1,0A2,0A3 ; Codes that up, down, right & left get translated to.
L1:
CMP AL,01B ; if not escape then we don't have this problem
JNZ >L0 ; L0 pops registers returns
MOV AX,2 ; BIOS call 2: is there any keyboard data pending?
CS CALL SIRIUS_BIOS
OR AL,AL ; AL=0 if no data pending, else AL=FF & AH=next char
JZ >L2 ; If no data pending, then it was the ESC key
CMP AH,'A' ; else check for valid code
JB >L2 ; If <'A' or >'D', then it was the ESC key
CMP AH,'D'
JA >L2
XOR AX,AX ; If we are to interpret the next key, we mustn't leave
CS CALL SIRIUS_BIOS ; it hanging. (It's returned in AL)
MOV BX,C1-'A' ; BX = offset of the Code table, with A=lower bound of AL
CS XLATB
JMP >L0
L2: ; It was only an ESC after all
MOV AL,01B
L0:
POP DI,SI,ES
RET
; SIRIUS_ADDR converts ES:DI from an offset that the caller recognizes,
; into an offset that the Sirius video recognizes. The mapping is
; variable to allow fast scrolling. Since the buffer repeats once
; in the memory map, the screen occupies contiguous memory, starting
; at an address 2047 or less. We also return DX set to the amount
; DI was changed, so that SUB DI,DX will restore DI.
SIRIUS_ADDR:
PUSH DS ; We have to ask the CRTC chip for the address
MOV DS,DX,0E800 ; of the first char on the screen
MOV B[0],12 ; Register 12 = high byte
MOV DH,B[1]
MOV B[0],13 ; Register 13 = low byte
MOV DL,B[1] ; Now ax = offset of line 0, col 0, in 16-bit words
AND DX,2047 ; It must be modulo-2048. This will always be the
; case anyway, unless the user's programme has screwed up the CRTC
SHL DX,1 ; now the offset is in bytes in DX
ADD DI,DX ; Now ES:DI points to the right address
POP DS ; DS is preserved
RET
;--------------------------
; DEC RAINBOW INTERFACE
;--------------------------
FUNC EQU 59+111
; BIOS interface routines for the DEC Rainbow A and B. Thanks to
; Vinzenz Esser, Moosburg, West Germany for writing this code.
; I have made format changes and minor optimizations.
DEC_KEYS: ; Key definition for DEC_RAINBOW_100
DB 0 ; Key code for Help key
#if IBMSIM
DB 0
#else
DB 097-FUNC ; Keypad_0 code is 097 (use instead of F1)
#endif
L1:
DB 094 ; Down Arrow key
DB 092 ; Next Screen key
DB 093 ; Up Arrow key
DB 091 ; Prev Screen key
DB 08D ; Find key (Home)
DB 090 ; Select key (Shift-F7)
DB 081 ; F2 Print Screen key (Alt-F9)
N_CONTROL_KEYS EQU $-L1
DW HELP_HELP ; Pointer to "HELP" message
L2:
DW DEC_COPY ; VID_COPY routine
DW DEC_ATTR ; VID_ATTR routine
DW RET ; VID_FIX not needed
#if IBMSIM
DW IBM_BELL,IBM_KEY
#else
DW DEC_BELL ; BIOS_BELL routine
DW DEC_KEY ; BIOS_KEY routine
#endif
DW RET ; BIOS_SAVE not needed
DW RET ; BIOS_RESTORE not needed
DW 0B800 ; VIDEO_SEG not needed but included for IBMSIM
DB 0E ; Normal-video attribute
DB 0F ; Reverse-video attribute
N_BIOS_CALLS EQU ($-L2)/2
; DEC_CONFIG is the BIOS initialization routine for the DEC RAINBOW 100
DEC_CONFIG:
SS DEC B[LAST_LINE+1] ; 24-line screen: move D86 command line up
CS DEC B[D86_LINES] ; also reduce the refresh lines count
MOV SI,DEC_KEYS ; Point to DEC's table of keycodes
CALL NEW_KEYS ; and plug these values into D86
MOV DX,DEC_INIT ; Clear screen
MOV AH,9
INT 021
RET
DEC_INIT:
DB 27,'[?3l' ; clear screen, reset all attributes, select 80 column mode
DB 27,'[24;1H$' ; position cursor to line 24, column 1
; DEC_KEY is the DEC RAINBOW 100 version of the BIOS_KEY routine.
;
; The BIOS call we use returns a character code in AL, and flag bits in AH:
; 01 for function key, 02 shift, 04 control key, 08 caps lock in effect.
;
; We remap the keys so that function keys return consecutive codes above 80H,
; according to the following chart:
;
; BIOS D86 Bios D86
; Key Code Code Key Code Code
; ------------------- ---- ---- ------------------- ---- ----
; F1 Hold Screen XXx n/a Prev Screen 23 91
; F2 Print Screen 03 81 Next Screen 25 92
; F3 Set-Up XXx n/a Up Arrow 27 93
; F4 05 82 Down Arrow 29 94
; F5 Break 65 A9 Right Arrow 2B 95
; F6 Interrupt 07 83 Left Arrow 2D 96
; F7 Resume 09 84 Keypad 0 2F 97
; F8 Cancel 0B 85 Keypad 1 32 98
; F9 Main Screen 0D 86 Keypad 2 35 99
; F10 Exit 0F 87 Keypad 3 38 9A
; F11 (ESC) XXx n/a Keypad 4 3B 9B
; F12 (BS) XXx n/a Keypad 5 3E 9C
; F13 (LF) XXx n/a Keypad 6 41 9D
; Addt'l Options 11 88 Keypad 7 44 9E
; Help 00 FF Keypad 8 47 9F
; Do 01 80 Keypad 9 4A A0
; F17 13 89 Keypad Dash 4D A1
; F18 15 8A Keypad Comma 50 A2
; F19 17 8B Keypad Period 53 A3
; F20 19 8C Keypad Enter 56 A4
; Find 1B 8D Keypad PF1 59 A5
; Insert Here 1D 8E Keypad PF2 5C A6
; Remove 1F 8F Keypad PF3 5F A7
; Select 21 90 Keypad PF4 62 A8
; Compose Character XXx n/a
;
; XXx These keys are trapped out for special processing by firmware:
; F1 Hold Screen Scroll lock toggle
; F3 Set-Up Enter SET-UP mode to change system parameters
; F11 (ESC) Always generates ESC character 1Bh
; F12 (BS) Always generates BS character 08
; F13 (LF) Always generates LF character 0Ah
; Compose Character Introduction key to a compose character
; sequence to generate characters from the
; DEC 8-bit multinational character set
; The code assigned to each function key is presented in the column 'D86' of
; the function key table above. Since on the DEC RAINBOW only 8 of the
; function keys F1-F10 are available to an application I had to remap the
; keys somewhat:
; IBM Key DEC Key
; F1 Keypad 0
; .. ..
; F10 Keypad 9
; Alt-F9 F2 Print Screen
; Shift-F7 Select
; Home Find
; Alt-F10 Help
; Since the following 3 'function keys' do not set the function key flag,
; they end up here too:
; F11 (ESC) Always generates ESC character 1Bh
; F12 (BS) Always generates BS character 08
; F13 (LF) Always generates LF character 0Ah
;
L0:
TEST AL ; Is this an 8-bit character?
JNS RET ; drop through if it is: we don't want it
DEC_KEY:
PUSH DI,ES ; save some registers
L1:
MOV DI,6 ; DEC BIOS function for GET KEY IF AVAILABLE
INT 24 ; do it
INC CL ; is a character available?
JNZ L1 ; keep looking, if not
POP ES,DI ; restore clobbered registers
TEST AH,1 ; Check function key flag
JZ L0 ; Go, if not a function key
TEST AL ; Check for help key
JZ RET ; Go, if help key
CMP AL,02F ; is the key in the divide-by-2 range?
JB >L2 ; jump if it is
MOV CL,3 ; key is in the divide-by-3 range: load divisor 3
MOV AH,0 ; extend keycode AL to AX
DIV CL ; divide by 3
ADD AL,088 ; add offset so that 2F,32,35,... becomes 97,98,99,...
CMP AL,097
IF E MOV AL,0A1
RET
L2: ; key code is in the divide-by-2 range
SHR AX,1 ; shift in low bit of AH: now 13,15,17... becomes 89,8A,8B...
RET
DEC_BELL: ; ring the bell on a DEC RAINBOW
PUSH DI,ES ; save registers
MOV AL,7 ; code 7 is BELL
MOV DI,0 ; function code for OUTPUT_AL
INT 24 ; output the bell code, to ring the bell
POP ES,DI ; restore trashed registers
RET
DEC_COPY: ; DEC RAINBOW 100 version of BIOS_COPY routine
PUSH BX,CX,SI,BP ; save registers across call
MOV AX,DI ; fetch starting output pointer
ADD AX,CX ; add in the number of characters
ADD AX,CX ; add twice, to reflect the output of words not bytes
PUSH AX ; simulated beyond-output is saved for return
MOV BP,DS ; Segment address in BP for function 14
CALL DEC_CONV_VIDEO ; convert DI from D86 value to line BL column BH
MOV AX,2 ; Set transfer type 2 = characters only
CALL DATA_TO_SCREEN ; Send data to screen
POP DI,BP,SI,CX,BX ; Restore registers
RET
DEC_ATTR: ; copy single attribute AL to screen at ES:DI
PUSH AX ; push the attribute byte AL onto the stack
CALL DEC_CONV_VIDEO ; Convert DI to line/column
MOV AX,1 ; Set transfer type 1 = attrib only
MOV CX,AX ; Transfer 1 character
MOV DX,SP ; Point to attribute byte
MOV BP,SS ; Segment address in BP
CALL DATA_TO_SCREEN ; send the attribute to the screen
POP AX ; pop attribute byte back off of stack
RET
; DATA_TO_SCREEN copies CX characters (no more than 80) from memory to the
; screen at column BH (1--80) line BL (1--24). Input AX tells whether to
; copy attributes from BP=DS:DX (AX=1), characters from DS:SI (AX=2) or both
; (AX=0).
DATA_TO_SCREEN:
#if IBMSIM
PUSH ES,DX,SI
CS MOV ES,VIDEO_SEG
ADD AX,AX
PUSH AX
MOV AL,BL
DEC AX
MOV AH,80
MUL AH
MOV BL,BH
DEC BX
MOV BH,0
ADD BX,AX
ADD BX,BX
MOV DI,BX
POP BX
CS CALL >L4[BX]
POP SI,DX,ES
RET
L4:
DW >L0,>L1,>L2
L0:
PUSH DI
CALL >L2
POP DI
L1:
XCHG SI,DX
L5:
INC DI
MOVSB
LOOP L5
XCHG DX,SI
RET
L2:
MOVSB
INC DI
LOOP L2
RET
#else
MOV DI,8 ; function number for DISABLE CURSOR
INT 24 ; call the DEC BIOS to disable the cursor
MOV DI,014 ; function number for WRITE TO SCREEN
INT 24 ; call the DEC BIOS to write to the screen
MOV DI,0A ; function number for ENABLE CURSOR
INT 24 ; call the DEC BIOS to enable the cursor
RET
#endif
; DEC_CONV_VIDEO converts the D86 video memory address in DI to line BL (1-24)
; and column BH (1-80)
DEC_CONV_VIDEO:
XCHG AX,DI ; swap the D86 address in AX
SHR AX,1 ; convert words to bytes
MOV BL,80 ; load the number of characters in a line
DIV BL ; compute column number AH, line number AL
MOV BX,0101 ; load offsets to convert first numbers from 0 to 1
ADD BX,AX ; add in the coordinates, for return in BH and BL
RET